﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RiaToDalLinq.Contracts;
using RiaToDalLinq.Configuration;
using System.ComponentModel.Composition.Hosting;
using System.Configuration;
using System.Reflection;
using System.ComponentModel.Composition;

namespace RiaToDalLinq.DalResolvers
{
    internal class DalResolverProvider
    {
        /// <summary>
        /// Import resolvers 
        /// </summary>
        [ImportMany(typeof(IDalResolver))]
        private IEnumerable<IDalResolver> CandidateResolvers { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private IDalResolver Resolver { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private static DalResolverProvider _instance { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private DalResolverProvider()
        {
            CandidateResolvers = null;
        }

        /// <summary>
        /// 
        /// </summary>
        public static IDalResolver Current
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new DalResolverProvider();

                    RiaToDalLinqConfiguration config = (RiaToDalLinqConfiguration)ConfigurationManager.GetSection("riaToDalLinqSettings");
                    AggregateCatalog cat = new AggregateCatalog();

                    if (config.ResolverType == Configuration.Types.RiaToDalLinqResolverType.Configuration)
                    {
                        cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetAssembly(_instance.GetType())));
                        CompositionContainer contnr = new CompositionContainer(cat);
                        contnr.ComposeParts(_instance);

                        _instance.Resolver = (from r in _instance.CandidateResolvers where r is ConfigurationDalResolver select r).FirstOrDefault();
                    }
                    else
                    {
                        cat.Catalogs.Add(new DirectoryCatalog(config.CustomResolverPluginDirectory));
                        CompositionContainer contnr = new CompositionContainer(cat);
                        contnr.ComposeParts(_instance);

                        _instance.Resolver = (from r in _instance.CandidateResolvers where r.GetType().Name.Equals(config.CustomResolverTypeName) select r).FirstOrDefault();
                    }

                    if (_instance.Resolver == null)
                    {
                        throw new ApplicationException(string.Format("No valid DAL resolver exports of name \"{0}\" could be found", config.CustomResolverTypeName));
                    }
                }

                return _instance.Resolver;
            }
        }
    }
}
